package com.fastloan.jn.mgt.process.service.impl;

import com.fastloan.jn.mgt.application.basic.model.JnApplication;
import com.fastloan.jn.mgt.application.basic.service.JnApplicationService;
import com.fastloan.jn.mgt.customer.model.JnCustomer;
import com.fastloan.jn.mgt.customer.service.JnCustomerService;
import com.fastloan.jn.mgt.process.core.ReturnData;
import com.fastloan.jn.mgt.process.dao.JnAppApproveMapper;
import com.fastloan.jn.mgt.process.dao.JnAppApproveUserMapper;
import com.fastloan.jn.mgt.process.dao.JnApplicationApprovalReviewMapper;
import com.fastloan.jn.mgt.process.exception.AppApproveException;
import com.fastloan.jn.mgt.process.model.JnAppApprove;
import com.fastloan.jn.mgt.process.model.JnAppApproveUser;
import com.fastloan.jn.mgt.process.model.JnApplicationApprovalReview;
import com.fastloan.jn.mgt.process.service.ProcessService;
import com.fastloan.jn.mgt.product.model.JnProductApprove;
import com.fastloan.jn.mgt.product.service.JnProductApproveService;
import com.fastloan.safe.mgt.user.model.CmuUser;
import com.fastloan.safe.mgt.user.service.CmuUserService;
import com.kawins.util.VerifyCodeUtil;
import org.kie.api.task.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.*;

import static com.fastloan.jn.mgt.application.basic.enums.ApplicationStatus.TO_SIGNED;
import static com.fastloan.jn.mgt.application.basic.enums.ApplicationStatus.UNDER_REVIEW;
import static java.util.stream.Collectors.toList;


/**
 * 进件流程服务层实现
 *
 * @author rankai
 *         createTime 2017-02-2017/2/6 9:49
 */
@Service
@Scope("prototype")
public class ProcessServiceImpl implements ProcessService {


    @Autowired
    private JnApplicationService tApplicationService;

    @Autowired
    private JnProductApproveService productApproveService;

    @Autowired
    private CmuUserService cmuUserService;

    @Autowired
    private JnAppApproveUserMapper appApproveUserMapper;

    @Autowired
    private JnAppApproveMapper appApproveMapper;

    @Autowired
    private JnApplicationApprovalReviewMapper applicationApprovalReviewMapper;

    @Autowired
    private JnCustomerService jnCustomerService;

//    @Autowired
//    private TApplicationContractService applicationContractService;

//    @Autowired
//    private MessageService messageService;
//
//    @Autowired
//    private TOrganizationService tOrganizationService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void applicationApproval(String applicationId) throws AppApproveException {
        JnApplication tApplication = tApplicationService.selectByPrimaryKey(applicationId);
//        if (tApplication.getApplyAmount() == null || tApplication.getApplyAmount().equals(0)) {
//            tApplicationService.modifyApplicationStatus(CREATE_ING, applicationId);
//            throw new AppApproveException("进件申请金额为空, 进件编号:" + applicationId);
//        }
        String customerId = tApplication.getCustomerId();
        JnCustomer jnCustomer = jnCustomerService.selectByPrimaryKey(customerId);
        if (jnCustomer.getModelResult() == null) {
            throw new AppApproveException("客户未进行模型评估, 进件编号:" + applicationId);
        }
        tApplication.setApplicationStatus(UNDER_REVIEW.getType());
        tApplicationService.updateByPrimaryKeySelective(tApplication);
        if (!approval(tApplication)) {
            tApplication.setApplicationStatus(TO_SIGNED.getType());
            tApplicationService.updateByPrimaryKeySelective(tApplication);
        }
    }

    /**
     * 插入审批
     *
     * @param appApproveId appApproveOneId
     */
    @Override
    @Transactional
    public ReturnData addAppApproveUser(String appApproveId) throws AppApproveException {
        return addAppApproveUserFind(appApproveId, Boolean.TRUE);
    }

    private ReturnData addAppApproveUserFind(String appApproveId, boolean flag) throws AppApproveException {
        JnAppApprove appApprove = appApproveMapper.selectByPrimaryKey(appApproveId);
        if (flag && appApprove.getIsReview().equals(1) && appApprove.getStatus().equals(1)) { //复核节点
            addUsers(appApprove, Boolean.TRUE);
            appApprove.setStatus(2);
            appApproveMapper.updateByPrimaryKeySelective(appApprove);
        } else if (!flag || appApprove.getIsReview().equals(0) || (appApprove.getIsReview().equals(1) &&
                (appApprove.getStatus().equals(2) || appApprove.getStatus().equals(0)))) {
            if (appApprove.getIsEnd().equals(1)) {
                if (!flag) {
                    addUsers(appApprove, Boolean.FALSE);
                } else {
                    appApprove.setStatus(3);
                    appApproveMapper.updateByPrimaryKeySelective(appApprove);
                    JnApplication application = tApplicationService.selectByPrimaryKey(appApprove.getAppId());
                    application.setApplicationStatus(TO_SIGNED.getType());
                    tApplicationService.updateByPrimaryKeySelective(application);
                    //  applicationContractService.insertContract(application.getId()); //若全部节点审核完成则插入客户签约信息
                    JnApplication tApplication = tApplicationService.selectByPrimaryKey(appApprove.getAppId());
//                    Integer orgType = ShiroKit.getOrgType();
//                    switch (OrgTypeEnum.getByType(orgType != null ? orgType : tOrganizationService.
//                            selectTopOrgByAppId(appApprove.getAppId()).getOrgType())) {
//                        case ORG_PER:
//                            messageService.messagePush("进件审批完成提示", "您编号为:" + tApplication.getApplicationCode() +
//                                    "的进件审批完成", tApplication.getCustomerManagerId(), PER_APPLICATION_APPROVE_COMPLETE);
//                            break;
//                        case ORG_COM:
//                            messageService.messagePush("进件审批完成提示", "您编号为:" + tApplication.getApplicationCode() +
//                                    "的进件审批完成", tApplication.getCustomerManagerId(), APPLICATION_APPROVE_COMPLETE);
//                            break;
//                        default:
//                            break;
//                    }
                    return new ReturnData(Boolean.FALSE);
                }
            } else if (appApprove.getIsEnd().equals(0)) {
                appApprove.setStatus(3);
                appApproveMapper.updateByPrimaryKeySelective(appApprove);
                if (flag) {
                    JnAppApprove appApproveOne = new JnAppApprove();
                    appApproveOne.setAppId(appApprove.getAppId());
                    appApproveOne.setStatus(0);
                    appApproveOne.setApproveSort(appApprove.getApproveSort() + 1);
                    JnAppApprove appApproveNext = appApproveMapper.selectOne(appApproveOne);
                    addUsers(appApproveNext, Boolean.FALSE);
                    appApproveNext.setStatus(1);
                    appApproveMapper.updateByPrimaryKeySelective(appApproveNext);
                } else {
                    addUsers(appApprove, Boolean.FALSE);
                    appApprove.setStatus(1);
                    appApproveMapper.updateByPrimaryKeySelective(appApprove);
                }
            }
        }
        return new ReturnData(Boolean.TRUE);
    }

    @Transactional
    public void returnApprove(String appApproveId, String newAppApproveId) {
        JnAppApprove appApprove = appApproveMapper.selectByPrimaryKey(newAppApproveId);
        Example example = new Example(JnAppApprove.class);
        example.createCriteria().andEqualTo("group", appApprove.getApproveGroup())
                .andGreaterThanOrEqualTo("sort", appApprove.getApproveSort()).andEqualTo("status", 3);
        List<JnAppApprove> appApproves = appApproveMapper.selectByExample(example);
        for (JnAppApprove appApproveOne : appApproves) {
            appApproveOne.setStatus(0);
            appApproveMapper.updateByPrimaryKeySelective(appApproveOne);
        }
        addUsers(appApprove, Boolean.FALSE);
        appApprove.setStatus(1);
        appApproveMapper.updateByPrimaryKeySelective(appApprove);
        JnAppApprove appApproveOne = new JnAppApprove();
        appApproveOne.setId(appApproveId);
        appApproveOne.setStatus(0);
        appApproveMapper.updateByPrimaryKeySelective(appApproveOne);
    }

    @Override
    @Transactional
    public void updateAppApprove(String appApproveId) {
        JnAppApprove appApproveOne = appApproveMapper.selectByPrimaryKey(appApproveId);
        JnAppApprove appApprove = new JnAppApprove();
        appApprove.setApproveGroup(appApproveOne.getApproveGroup());
        List<JnAppApprove> appApproves = appApproveMapper.select(appApprove);
        for (JnAppApprove appApproveNew : appApproves) {
            appApproveNew.setStatus(3);
            appApproveMapper.updateByPrimaryKeySelective(appApproveNew);
        }
    }

    private boolean approval(JnApplication application) throws AppApproveException {
        JnProductApprove productApprove = new JnProductApprove();
        productApprove.setProductId(application.getProductId());
        List<JnProductApprove> productApproves = productApproveService.select(productApprove);
        if (productApproves == null) {
            throw new AppApproveException("没找到节点");
        }

        //获取审批顺序链
        JnProductApprove approve = new JnProductApprove();
        approve.setProductId(application.getProductId());
        List<JnProductApprove> productApproveLink = productApproveService.select(approve).parallelStream()
                .filter(productApproveTemp -> productApproveTemp.getOrderBy() != null && !productApproveTemp.getFinalNode().equals(1))
                .sorted(Comparator.comparing(JnProductApprove::getOrderBy))
                .collect(toList());

        if (productApproveLink == null) {
            throw new AppApproveException("获取审批顺序链失败");
        }

        List<JnProductApprove> newProductApproves = new ArrayList<>();
        for (JnProductApprove approves : productApproveLink) {
            if (approves.getIsLoanLimit().equals(0) || (approves.getIsLoanLimit().equals(1) && approves.getLoanLimit().longValue() <=
                    application.getApplyAmount().longValue())) {
                newProductApproves.add(approves);
            }
        }
        if (newProductApproves.size() == 0) {
            tApplicationService.updateByPrimaryKeySelective(application);
            //    applicationContractService.insertContract(application.getId()); //若全部节点审核完成则插入客户签约信息
            application.setApplicationStatus(TO_SIGNED.getType());
            tApplicationService.updateByPrimaryKeySelective(application);
            return Boolean.FALSE;
        }

        //插入审批顺序链
        String textCode = "";
        int count = 0;
        boolean flag = Boolean.FALSE;
        for (int i = 0; newProductApproves.size() > i; i++) {
            flag = Boolean.TRUE;
            count++;
            JnProductApprove productApproveOne = newProductApproves.get(i);
            if ("".equals(textCode)) {
                while (true) {
                    textCode = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_ONLY, 9, null);
                    JnAppApprove appApprove = new JnAppApprove();
                    appApprove.setAppId(application.getId());
                    appApprove.setApproveGroup(textCode);
                    List<JnAppApprove> appApproves = appApproveMapper.select(appApprove);
                    if (appApproves.size() == 0) {
                        break;
                    }
                }
            }
            JnAppApprove appApprove = JnAppApprove.JnAppApproveBuilder.aJnAppApprove()
                    .withAppId(application.getId())
                    .withProductApproveId(productApproveOne.getProductId())
                    .withApproveSort(count)
                    .withCreateTime(new Date())
                    .withIsReview(productApproveOne.getIsReviewNode())
                    .withApproveRoles(productApproveOne.getAssessingOfficer())
                    .withIsLoanLimit(productApproveOne.getIsLoanLimit())
                    .withLoanLimit(productApproveOne.getLoanLimit())
                    .withLoanMeetingType(productApproveOne.getLoanMeetingType())
                    .withApproveGroup(textCode)
                    .withLoanMeeting(productApproveOne.getIsLoanMeeting())
                    .withApproveName(productApproveOne.getNodeName())
                    .build();
            appApprove.setStatus(i == 0 ? 1 : 0);//1 审批中 0待审批
            appApprove.setIsEnd(i == newProductApproves.size() - 1 ? 1 : 0);
            appApproveMapper.insertSelective(appApprove);
            if (i == 0) {
                addAppApproveUserFind(appApprove.getId(), Boolean.FALSE);
            }
        }
        return flag;
    }

    /**
     * 筛选审批用户
     *
     * @param appApprove 审批节点信息
     * @return 筛选出的审批用户
     */
    private List<CmuUser> getApproveUser(JnAppApprove appApprove) {
        String approveRoles = appApprove.getApproveRoles();
        List<String> stringList = Arrays.stream(approveRoles.split(",")).collect(toList());
        Example example = new Example(CmuUser.class);
        example.createCriteria().andIn("id", stringList);
        return cmuUserService.selectByExample(example);
    }

    private void addUsers(JnAppApprove appApprove, boolean flag) {
        JnApplication tApplication = tApplicationService.selectByPrimaryKey(appApprove.getAppId());
        Map<String, Object> map = new HashMap<>();
        map.put("approveId", appApprove.getId());
        if (appApprove.getLoanMeeting().equals(0)) {//非审贷会
            List<CmuUser> approveUser = getApproveUser(appApprove);
            for (CmuUser user : approveUser) {
                JnAppApproveUser appApproveUser = new JnAppApproveUser();
                appApproveUser.setUserId(user.getId());
                appApproveUser.setCreateTime(new Date());
                appApproveUser.setApplicationId(tApplication.getId());
                appApproveUser.setAppApproveId(appApprove.getId());
                if (flag) {
                    appApproveUser.setIsReview(1);
                } else {
                    appApproveUser.setIsReview(0);
                }
                appApproveUser.setStatus(0);
                appApproveUserMapper.insertSelective(appApproveUser);
                map.put("userId", user.getId());
                map.put("applicationId", appApprove.getAppId());
                map.put("appApproveUserId", appApproveUser.getId());
//                Integer orgType = ShiroKit.getOrgType();
//                if (Objects.equals(orgType != null ? orgType : tOrganizationService.selectTopOrgByAppId(appApprove.getAppId()),
//                        OrgTypeEnum.ORG_COM.getValue())) {
//                    messageService.messagePush("审批提示", "您有一个进件需要审批, 进件编号:" +
//                                    tApplication.getApplicationCode(), user.getId(), APPLICATION_APPROVE, map,
//                            Lists.newArrayList(CUSTOMER_MANAGER, EXPERT, PRODUCT_MANAGER));
//                } else {
//                    messageService.messagePush("审批提示", "您有一个进件需要审批, 进件编号:" +
//                                    tApplication.getApplicationCode(), user.getId(), PER_APPLICATION_APPROVE, map,
//                            Lists.newArrayList(PER_CUSTOMER_MANAGER, EXPERT, PER_PRODUCT_MANAGER));
//                }
            }
        } else if (appApprove.getLoanMeeting().equals(1)) { //审贷会
            JnApplicationApprovalReview applicationApprovalReview = new JnApplicationApprovalReview();
            applicationApprovalReview.setAppId(appApprove.getAppId());
            applicationApprovalReview.setReviewConditions(appApprove.getLoanMeetingType());
            applicationApprovalReview.setApprovalId(appApprove.getId());
            applicationApprovalReview.setReviewStatus(0);
            applicationApprovalReviewMapper.insertSelective(applicationApprovalReview);
//            TOrganization organization = tOrganizationService.selectTopOrgByAppId(appApprove.getAppId());
//            Integer orgType = organization.getOrgType();
            List<CmuUser> users = new ArrayList<>();
//            if (orgType == OrgTypeEnum.ORG_PER.getValue()) {
//                users = cmuUserService.selectUserByRole(ShiroEnum.PER_PRODUCT_MANAGER.getType(), organization.getId());
//            } else if (orgType == OrgTypeEnum.ORG_COM.getValue()) {
//                users = cmuUserService.selectUserByRole(ShiroEnum.PRODUCT_MANAGER.getType(), organization.getId());
//            }
//            for (User user : users) {
//                map.put("approvalReviewId", applicationApprovalReview.getId());
//                map.put("applicationId", tApplication.getId());
//                if (orgType.equals(OrgTypeEnum.ORG_COM.getValue())) {
//                    messageService.messagePush("排审提示", "您有一个进件需要排审, 进件编号:" +
//                                    tApplication.getApplicationCode(), user.getId(), APPROVE_APPROVING_MEMBER, map
//                            , Lists.newArrayList(PRODUCT_MANAGER));
//                } else {
//                    messageService.messagePush("排审提示", "您有一个进件需要排审, 进件编号:" +
//                                    tApplication.getApplicationCode(), user.getId(), PER_APPROVE_APPROVING_MEMBER, map
//                            , Lists.newArrayList(PER_PRODUCT_MANAGER));
//                }
//            }
        }
    }
}
